package com.xls.resource.dialog.utils.download;

import android.os.Environment;

import androidx.annotation.NonNull;

import com.lzz.bottomencapsulation.utils.LUtils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.rxjava3.functions.Function;
import io.reactivex.rxjava3.observers.DisposableObserver;
import io.reactivex.rxjava3.schedulers.Schedulers;
import okhttp3.OkHttpClient;
import okhttp3.ResponseBody;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory;

public class DownloadUtils {
    private static final String TAG = "DownloadUtils";
    private static final int DEFAULT_TIMEOUT = 15;
    private Retrofit retrofit;
    private DownloadListener listener;
    private String FILE_SAVE_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/box2023/";

    public DownloadUtils(String baseUrl,long id, DownloadListener listener) {
        this.listener = listener;
        this.id=id;
        JsDownloadInterceptor mInterceptor = new JsDownloadInterceptor(listener,id);
        OkHttpClient httpClient = new OkHttpClient.Builder()
                .addInterceptor(mInterceptor)
                .retryOnConnectionFailure(true)
                .connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                .build();
        retrofit = new Retrofit.Builder()
                .client(httpClient)
                .baseUrl(baseUrl)
                .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
                .build();
    }
    /**
     * 开始下载
     *
     * @param url
     * @param filePath
     * @param subscriber
     */
    DisposableObserver observable;

    public DisposableObserver getObservable() {
        return observable;
    }
    long id;
    public void download( long id,@NonNull String url, final String filePath, DisposableObserver subscriber) {
        this.url=url;
        this.id=id;
        observable=subscriber;
        listener.onStartDownload(id);
        // subscribeOn()改变调用它之前代码的线程
        // observeOn()改变调用它之后代码的线程
        retrofit.create(IApiserver.class)
                .download(url).subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .map(new Function<ResponseBody, InputStream>() {
                    @Override
                    public InputStream apply(ResponseBody responseBody) throws Throwable {
                        return responseBody.byteStream();
                    }
                })
                .observeOn(Schedulers.computation()) // 用于计算任务
                .doOnNext(new Consumer<InputStream>() {
                    @Override
                    public void accept(InputStream inputStream) throws Throwable {
                        LUtils.e("------------开始下载");
                        writeFile(inputStream, filePath);
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber);

    }
    public void downloadAPK( long id,@NonNull String url, final String filePath) {
        this.url=url;
        this.id=id;
        observable=new DisposableObserver() {
            @Override
            public void onNext(Object o) {

            }

            @Override
            public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {
                if (listener!=null)listener.onError(id,e.toString());
            }

            @Override
            public void onComplete() {
                if (listener!=null)listener.onComplete(id);
            }
        };
        listener.onStartDownload(id);
        // subscribeOn()改变调用它之前代码的线程
        // observeOn()改变调用它之后代码的线程
        retrofit.create(IApiserver.class)
                .download(url).subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .map(new Function<ResponseBody, InputStream>() {
                    @Override
                    public InputStream apply(ResponseBody responseBody) throws Throwable {
                        return responseBody.byteStream();
                    }
                })
                .observeOn(Schedulers.computation()) // 用于计算任务
                .doOnNext(new Consumer<InputStream>() {
                    @Override
                    public void accept(InputStream inputStream) throws Throwable {
                        LUtils.e("------------开始下载");
                        writeFile(inputStream, filePath);
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observable);

    }
    String url;

    public String getUrl() {
        return url;
    }

    public long getId() {
        return id;
    }

    private void writeFile(InputStream inputString, String filePath) {
        File file = new File(filePath);
        if (file.exists()) {
            file.delete();
        }

        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(file);

            byte[] b = new byte[1024];

            int len;
            while ((len = inputString.read(b)) != -1) {
                fos.write(b,0,len);
            }
            inputString.close();
            fos.close();

        } catch (FileNotFoundException e) {
            listener.onFail(id,"FileNotFoundException");
        } catch (IOException e) {
            listener.onFail(id,"IOException");
        }
    }
}
